﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Algobox.Structure.Finance.Prices;
using Algobox.Objects.Finance.Assets.Stock;
using Algobox.Objects.Finance;
using Algobox.Feeds.Finance.MarketData;

namespace Algobox.Structure.Finance.Strategies.PriceMatrix
{
    public class PriceMatrixView : INotifyPropertyChanged, IMarketUpdateBid, IMarketUpdateAsk, IMarketUpdateLast, IMarketUpdatePhase
    {
        public PriceMatrixView(IStock stock)
        {
            _stock = stock;
        }

        IStock _stock;

        public string Symbol { get { return _stock.ToString(); } }

        Phases.Phase _phase;
        DateTime _lastTimeStamp;
        double _lastPrice;
        double _askPrice;
        double _bidPrice;
        ulong _lastQuantity;
        ulong _askQuantity;
        ulong _bidQuantity;

        double _open;
        double _high;
        double _low;
        double _close;
        ulong _volume;
        double _vwap;

        public Phases.Phase Phase { get { return _phase; } set { _phase = value; NotifyPropertyChanged("Phase"); } }

        public DateTime LastTimeStamp { get { return _lastTimeStamp; } set { _lastTimeStamp = value; NotifyPropertyChanged("LastTimeStamp"); } }
        public double LastPrice { get { return _lastPrice; } set { _lastPrice = value; NotifyPropertyChanged("LastPrice"); } }
        public ulong LastVolume { get { return _lastQuantity; } set { _lastQuantity = value; NotifyPropertyChanged("LastVolume"); } }
        public double AskPrice { get { return _askPrice; } set { _askPrice = value; NotifyPropertyChanged("AskPrice"); } }
        public ulong AskVolume { get { return _askQuantity; } set { _askQuantity = value; NotifyPropertyChanged("AskVolume"); } }
        public double BidPrice { get { return _bidPrice; } set { _bidPrice = value; NotifyPropertyChanged("BidPrice"); } }
        public ulong BidVolume { get { return _bidQuantity; } set { _bidQuantity = value; NotifyPropertyChanged("BidVolume"); } }

        //public decimal Change { get { return _security.Prices.Last.Price != 0 ? LastPrice - Open : Close - Open; } }
        //public decimal ChangePercent { get { return 1m + (Open / (LastPrice - Open) / 100m); } }

        public double Open { get { return _open; } set { _open = value; NotifyPropertyChanged("Open"); } }
        public double High { get { return _high; } set { _high = value; NotifyPropertyChanged("High"); } }
        public double Low { get { return _low; } set { _low = value; NotifyPropertyChanged("Low"); } }
        public double Close { get { return _close; } set { _close = value; NotifyPropertyChanged("Close"); } }
        public ulong Volume { get { return _volume; } set { _volume = value; NotifyPropertyChanged("Volume"); } }

        public double VWAP { get { return _vwap; } set { _vwap = value; NotifyPropertyChanged("VWAP"); } }
        
        public string Index 
        { 
            get 
            {
                if (_stock is StockSecurity)
                    return ((StockSecurity)_stock).Index;
                else if (_stock is StockListing)
                    return ((StockListing)_stock).Security.Index;
                else
                    throw new NotImplementedException();
            }
        }
        public string Sector
        {
            get
            {
                if (_stock is StockSecurity)
                    return ((StockSecurity)_stock).Sector;
                else if (_stock is StockListing)
                    return ((StockListing)_stock).Security.Sector;
                else
                    throw new NotImplementedException();
            }
        }
        public string Industry
        {
            get
            {
                if (_stock is StockSecurity)
                    return ((StockSecurity)_stock).IndustryGroup;
                else if (_stock is StockListing)
                    return ((StockListing)_stock).Security.IndustryGroup;
                else
                    throw new NotImplementedException();
            }
        }

        public void OnPriceBid(IStock stock, Objects.Finance.Prices.PriceVolume bid)
        {
            BidPrice = bid.Price;
            BidVolume = bid.Volume;
        }

        public void OnPriceAsk(IStock stock, Objects.Finance.Prices.PriceVolume ask)
        {
            AskPrice = ask.Price;
            AskVolume = ask.Volume;
        }

        public void OnPriceLast(IStock stock, Objects.Finance.Prices.PriceVolume last)
        {
            LastTimeStamp = last.TimeStamp;
            Volume += last.Volume;
            Close = last.Price;
            if (last.Price > _high)
                High = last.Price;
            if (_low == 0 || last.Price < _low)
                Low = last.Price;
            if (_open == 0)
                Open = last.Price;
            LastPrice = last.Price;
            LastVolume = last.Volume;
            if (stock.Prices.VWAP != 0)
                VWAP = stock.Prices.VWAP;
        }

        public void OnPhaseChange(IStock stock)
        {
            Phase = stock.Phase;
        }

        
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        
    }
}
